package com.dutao.service;

import com.dutao.entity.RegionStates;
import lombok.Data;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.Resource;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.PostConstruct;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Data
public class CovidDataProvider {

    //public final static String COVID_DATASOURCE_URL1 = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv";

    public final static String COVID_DATASOURCE_CONFIRM = "https://gitee.com/dgut-sai/COVID-19/raw/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv";

    public final static String COVID_DATASOURCE_DEATH = "https://gitee.com/dgut-sai/COVID-19/raw/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_global.csv";

    public final static String COVID_DATASOURCE_RECOVER = "https://gitee.com/dgut-sai/COVID-19/raw/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_recovered_global.csv";

    private static final Logger log = LoggerFactory.getLogger(CovidDataProvider.class);
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    private List<RegionStates> data = new ArrayList<>();

    private Map<String, Object> DataMap = new HashMap<>();

    @Autowired
    private RestTemplate restTemplate;

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Scheduled(cron = "0 0 1 * * *")
    @PostConstruct
    public void initCovidData() {
        List<Integer> sevenSum = new ArrayList();//七个时间段数据，渲染chart
        for (int i = 0; i < 7; i++){
            sevenSum.add(0);
        }
        try {
            Iterable<CSVRecord> records = getCSVRecord(COVID_DATASOURCE_CONFIRM);
            for (CSVRecord record : records) {
                this.data.add(new RegionStates()
                        .setState(record.get("Province/State"))
                        .setCountry(record.get("Country/Region"))
                        .setLatestTotalCases(Integer.valueOf(record.get(record.size() - 1)))
                        .setDiffFromPrevDay(Integer.valueOf(record.get(record.size() - 1))
                                - Integer.valueOf(record.get(record.size() - 2))));

                for (int i = 7; i >= 1; i--)
                    sevenSum.set(7-i,sevenSum.get(7-i)+Integer.valueOf(record.get(record.size() - 30*i)));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.DataMap.put("sevenSum",sevenSum);
        initDeathRecover();
        log.info("Update covid data in {}", dateFormat.format(new Date()));
    }

    /**
     * 死亡、恢复 数量
     */
    public void initDeathRecover(){
        //记录七个时间段数据
        List<Integer> sevenDeath = new ArrayList();
        List<Integer> sevenRecover = new ArrayList();
        for (int i = 0; i < 7; i++){
            sevenDeath.add(0);
            sevenRecover.add(0);
        }
        try {
            Iterable<CSVRecord> deathRecords = getCSVRecord(COVID_DATASOURCE_DEATH);
            Iterable<CSVRecord> recoverRecords = getCSVRecord(COVID_DATASOURCE_RECOVER);
            int death = 0,recover = 0;
            int cdeath = 0,crecover = 0;
            for (CSVRecord record : deathRecords) {
                death += Integer.valueOf(record.get(record.size() - 1));
                if(record.get("Country/Region").equals("China")||record.get("Province/State").equals("Taiwan")){
                    cdeath += Integer.valueOf(record.get(record.size() - 1));
                }
                for (int i = 7; i >= 1; i--)
                    sevenDeath.set(7-i,sevenDeath.get(7-i)+Integer.valueOf(record.get(record.size() - 30*i)));
            }
            for (CSVRecord record : recoverRecords) {
                recover += Integer.valueOf(record.get(record.size() - 1));
                if(record.get("Country/Region").equals("China")||record.get("Province/State").equals("Taiwan")){
                    crecover += Integer.valueOf(record.get(record.size() - 1));
                }
                for (int i = 7; i >= 1; i--)
                    sevenRecover.set(7-i,sevenRecover.get(7-i)+Integer.valueOf(record.get(record.size() - 30*i)));
            }
            this.DataMap.put("death",death);
            this.DataMap.put("recover",recover);
            this.DataMap.put("cdeath",cdeath);
            this.DataMap.put("crecover",crecover);
            this.DataMap.put("sevenDeath",sevenDeath);
            this.DataMap.put("sevenRecover",sevenRecover);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过URL获得CSV
     *
     * @param url
     * @return
     * @throws Exception
     */
    public Iterable<CSVRecord> getCSVRecord(String url) throws Exception {
        URI uri = UriComponentsBuilder.fromUriString(url).build(42);
        RequestEntity<Void> requestEntity = RequestEntity
                .get(uri)
                .header("User-Agent", "Mozilla/5.0")
                .build();
        ResponseEntity<Resource> response = restTemplate.exchange(requestEntity, Resource.class);
        Resource body = response.getBody();
        Reader in = new InputStreamReader(body.getInputStream());
        return CSVFormat.RFC4180.withFirstRecordAsHeader().parse(in);
    }


}
